use mysql::{prelude::FromRow, prelude::Queryable, OptsBuilder};

pub struct DbConfig {
    pub host: String,
    pub port: u16,
    pub db_name: String,
    pub user: String,
    pub pass: String,
}

/**
 * 初始化数据库连接。
 *
 * 此函数创建一个新的数据库连接，并返回一个连接池。
 * 如果连接失败，函数将打印错误消息并退出进程。
 *
 * 返回:
 * - mysql::Conn: 数据库连接池。
 */

pub(crate) struct Db {
    pub conn: mysql::Conn,
}
impl Db {
    pub fn new(config: DbConfig) -> Db {
        let conn = Db::init_conection(config);
        Db { conn }
    }
    pub fn init_conection(config: DbConfig) -> mysql::Conn {
        println!("初始化数据库连接");
        let conn = OptsBuilder::new()
            .ip_or_hostname(Some(config.host))
            .db_name(Some(config.db_name))
            .user(Some(config.user))
            .pass(Some(config.pass))
            .tcp_port(config.port);
        let pool = match mysql::Conn::new(conn) {
            Ok(p) => p,
            Err(e) => {
                eprintln!("数据库连接失败: {}", e);
                std::process::exit(1);
            }
        };
        println!("数据库连接成功");
        pool
    }
    pub fn query_generic<T>(&mut self, query: &str) -> Result<Vec<T>, mysql::Error>
    where
        T: FromRow,
    {
        self.conn.query_map(query, |row| T::from_row(row))
    }
}
